﻿using System;
using System.Collections.Concurrent;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;


namespace FinalTest_Algonrithm
{
    public class SZLightModuleDLL
    {
        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_init_lib(string configPath);

        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_run(string str_DeviceName);

        [DllImport("Hy_SZCapture.dll")]
        public static unsafe extern int hy_dtk_cap(string str_DeviceName, byte* bmpData, ref int n_Width, ref int n_Height);

        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_stop(string str_DeviceName);

        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_get_VoltageCurrent(string str_DeviceName, ref double voltage, ref double current);
        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_ispiic(string str_DeviceName);
        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_writeiic(string dtkname, int slave, int addr, int value, int mode);
        [DllImport("Hy_SZCapture.dll")]
        public static extern bool hy_dtk_readiic(string dtkname, int slave, int addr, ref int value, int mode);

    }

    public class VIData
    {
        public double V1 = 0;
        public double I1 = 0;
        public double V2 = 0;
        public double I2 = 0;
    }




    public class ModuleCaptureMgr
    {
        public Func<int, string> GetIndex;
        public VIData VIData = null;
        private static ModuleCaptureMgr moduleMgr;
        private static object obj = new object();
        Thread threadMonitor = null;
        public Func<VIData> func_GetVI = null;

        int w, h;

        bool b_Run = true;
        public static ModuleCaptureMgr Instance
        {
            get
            {
                lock (obj)
                {
                    if (moduleMgr == null)
                    {

                        if (moduleMgr == null)
                        {
                            moduleMgr = new ModuleCaptureMgr();
                        }

                    }
                    return moduleMgr;
                }
            }
        }
        public ModuleCaptureMgr()
        {
            threadMonitor = new Thread(new ThreadStart(MonitorRun));
            threadMonitor.IsBackground = true;
            threadMonitor.Start();
        }
        ~ModuleCaptureMgr()
        {

            b_Run = false;
        }
        private void MonitorRun()
        {
            while (b_Run)
            {
                Thread.Sleep(30);
                try
                {
                    if (func_GetVI != null)
                    {
                        VIData = func_GetVI();
                    }

                }
                catch (Exception)
                {
                }
            }
        }

        public bool Init(string strFile, int w, int h)
        {
            var i = false;
            this.h = h;
            this.w = w;
            try
            {
                i = SZLightModuleDLL.hy_init_lib(strFile);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            return i;
        }
        public bool Play(int nDeviceIndex)
        {
            if (GetIndex != null)
            {
                string strName = GetIndex(nDeviceIndex);
                return SZLightModuleDLL.hy_dtk_run(strName);
            }
            else
                return false;
        }

        public bool Stop(int nDeviceIndex)
        {
            if (GetIndex != null)
            {
                return SZLightModuleDLL.hy_dtk_stop(GetIndex(nDeviceIndex));
            }
            else
                return false;

        }
        public bool CaptureToBmpRGB(int DeviceID, int n_Frame, ref Bitmap bt)
        {
            try
            {
                if (GetIndex != null)
                {
                    string str_DeviceName = GetIndex(DeviceID);
                    int n_Width = w;
                    int n_Height = h;
                    int nRet = 0;
                    byte[] imageData = new byte[n_Width * n_Height * 3];
                    unsafe
                    {
                        fixed (byte* byteBuffer = imageData)
                        {
                            nRet = SZLightModuleDLL.hy_dtk_cap(str_DeviceName, byteBuffer, ref n_Width, ref n_Height);
                        }
                    }
                    bt = ConvertBinaryToBitmap(imageData, n_Width, n_Height);



                    return nRet == 1;
                }
                else
                    return false;

            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public bool GetVI(int nDeviceIndex, ref double voltage, ref double current)
        {
            if (GetIndex != null)
            {
                return SZLightModuleDLL.hy_dtk_get_VoltageCurrent(GetIndex(nDeviceIndex), ref voltage, ref current);
            }
            else
                return false;
        }


        public bool CloseISP(int nDeviceIndex)
        {
            if (GetIndex != null)
            {
                string strName = GetIndex(nDeviceIndex);
                return SZLightModuleDLL.hy_dtk_ispiic(strName);
            }
            else
                return false;

        }

        public bool WriteI2C(int nDeviceIndex, int slave, int addr, ref int value, int mode)
        {
            if (GetIndex != null)
            {
                string strName = GetIndex(nDeviceIndex);
                return SZLightModuleDLL.hy_dtk_writeiic(strName, slave, addr, value, mode);
            }
            else
                return false;

        }

        public bool ReadI2C(int nDeviceIndex, int slave, int addr, ref int value, int mode)
        {
            if (GetIndex != null)
            {
                string strName = GetIndex(nDeviceIndex);
                return SZLightModuleDLL.hy_dtk_readiic(strName, slave, addr, ref value, mode);
            }
            else
                return false;

        }


        public static byte[] ConvertBitmapToByteArray(Bitmap bitmap)
        {
            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
            try
            {
                int bytesPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8;
                int imageDataSize = bitmapData.Stride * bitmap.Height;
                byte[] imageData = new byte[imageDataSize];
                Marshal.Copy(bitmapData.Scan0, imageData, 0, imageDataSize);
                return imageData;
            }
            finally
            {
                bitmap.UnlockBits(bitmapData);
            }
        }

        public static Bitmap ConvertBinaryToBitmap(byte[] imageData, int nWidth, int nHeight)
        {
            Bitmap bitmap = new Bitmap(nWidth, nHeight, PixelFormat.Format24bppRgb);
            try
            {
                BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, nWidth, nHeight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
                IntPtr scan = bitmapData.Scan0;
                int length = bitmapData.Stride * nHeight;
                Marshal.Copy(imageData, 0, scan, length);
                bitmap.UnlockBits(bitmapData);
                return bitmap;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return bitmap;
            }
        }

    }
}
